﻿using MongoDB.Driver;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.ESG.Entities;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.ScreeningTool.Synchronization.Handlers.ESG
{
    public class EsgResearchProfileHandler : IHandler<EsgResearchProfile>, IHasClientFacingProduct
    {
        public ClientFacingProduct ClientFacingProduct { get; set; }

        public ProjectionDefinition<EsgResearchProfile> GetProjection(ProjectionDefinitionBuilder<EsgResearchProfile> builder)
        {
            var projectionDefinition = builder
                .Include(x => x.SPLCode)
                .Include(x => x.AnalystCommentary)
                .Include(x => x.BusinessModelComment)
                .Include(x => x.ExposureComment)
                .Include(x => x.ManagementAndExposureComment)
                .Include(x => x.OverallAssessment)
                .Include(x => x.LastUpdate)
                .Include(x => x.LastFullReviewDate)
                .Include(x => x.LastAnnualReportDate)
                .Include(x => x.LastCSRDate)
                .Include(x => x.LastFeedbackReceivedDate)
                .Include(x => x.LastFeedbackRequestDate);

            if (ClientFacingProduct.IsDS())
            {
                projectionDefinition = projectionDefinition
                    .Include("ExtraIndicators.Template.Number")
                    .Include("ExtraIndicators.Template.Name")
                    .Include("ExtraIndicators.SelectedAnswer.Score");
            }

            return projectionDefinition;
        }

        public IEnumerable<ExtraElement> GetExtraElements(EsgResearchProfile entity)
            => EnumerableExtensions.Concat(
                entity.GetExtraElements(),
                entity.ExtraIndicators?.GetExtraElements());
    }

    public static class EsgResearchProfileExtensions
    {
        public static IEnumerable<ExtraElement> GetExtraElements(this EsgResearchProfile entity)
            => new ExtraElementList
            {
                { "SPL Code",                        entity.SPLCode                                   },
                { "Analyst Commentary",              entity.AnalystCommentary                         },
                { "Overall Business Model Narrative",entity.BusinessModelComment                      },
                { "Overall Exposure Narrative",      entity.ExposureComment                           },
                { "Overall Management Narrative",    entity.ManagementAndExposureComment              },
                { "Overall Assessment",              entity.OverallAssessment                         },
                { "Date last update",                entity.LastUpdate.NullIfMinValue()               },
                { "Date last full update",           entity.LastFullReviewDate.NullIfMinValue()       },
                { "Last annual report date",         entity.LastAnnualReportDate.NullIfMinValue()     },
                { "Last CSR report date",            entity.LastCSRDate.NullIfMinValue()              },
                { "Last feedback received date",     entity.LastFeedbackReceivedDate.NullIfMinValue() },
                { "Last feedback requested date",    entity.LastFeedbackRequestDate.NullIfMinValue()  },
            };

        public static IEnumerable<ExtraElement> GetExtraElements(this IEnumerable<RPIndicatorExtended> entities)
            => entities.SelectMany(x =>
            {
                var key = $"{x.Template.Number.Trim()} {x.Template.Name.Trim()}";
                return new ExtraElementList
                {
                    { $"{key}-Raw Score", x.SelectedAnswer?.Score?.Bind(score => new Apg(score)) },
                };
            });
    }

    public class Apg
    {
        public Apg(object value)
        {
            Value = value;
        }

        public object Value { get; }
    }
}
